from django.core.cache import cache
from django.db import models

from apps.tcpserver.cache import SensorCache
from util.typing import DjangoModelTyping


class Devices(models.Model):
    id = models.BigAutoField(
        primary_key=True
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    hardware_model = models.CharField(
        max_length=34
    )
    manufacture_tmie = models.DateTimeField()
    hardware_version = models.CharField(
        max_length=18
    )
    software_version = models.CharField(
        max_length=18
    )
    device_serial_number = models.CharField(
        unique=True,
        max_length=66,

    )
    alias = models.CharField(
        max_length=255
    )
    region = models.ManyToManyField(
        'common.Region',
        blank=True,
        null=True
    )
    mode = models.IntegerField()
    setting = models.IntegerField()
    user = models.ManyToManyField(
        'user.User',
        verbose_name='设备关联到用户'
    )

    longitude = models.DecimalField(
        decimal_places=2,
        max_digits=10,
        default=0,
        verbose_name="经度"
    )
    latitude = models.DecimalField(
        decimal_places=2,
        max_digits=10,
        default=0,
        verbose_name="纬度"
    )

    @property
    def status(self):
        return cache.get(f'{self.device_serial_number}_{self.id}', )

    @status.setter
    def status(self, value):
        cache.set(f'{self.device_serial_number}_{self.id}', value, timeout=200)

    class Meta(DjangoModelTyping):
        permissions = (
            ('devices_post', '添加设备'),
            ('devices_patch', '修改设备'),
            ('devices_delete', '删除设备'),
            ('devices_get', '查询设备'),
        )
        default_permissions = ()
        db_table = 'devices'


class Controls(models.Model):
    EFFECTIVE_ON = 1
    EFFECTIVE_OFF = 0

    EFFECTIVE = (
        (EFFECTIVE_ON, '可用'),
        (EFFECTIVE_OFF, '不可用'),
    )
    # 0：手动 1：定时 2：自动
    MODE_AUTO = 2
    MODE_MANUAL = 0
    MODE_TIMING = 1

    modes = (
        (MODE_AUTO, '自动'),
        (MODE_MANUAL, '手动'),
        (MODE_TIMING, '定时'),
    )

    ON = 0
    OFF = 1

    STATUS = (
        (ON, '启用'),
        (OFF, '禁用'),
    )

    id = models.AutoField(
        primary_key=True,
        unique=True,
        verbose_name='主键'
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    devices = models.ForeignKey(
        Devices,
        on_delete=models.CASCADE
    )
    number = models.CharField(
        max_length=255,
        verbose_name='编号',
        null=False
    )
    alias = models.CharField(
        max_length=255,
        verbose_name='控制器别名'
    )
    effective = models.IntegerField(
        verbose_name='有效标识',
        null=True
    )
    status = models.IntegerField(
        verbose_name='是否启用',
        null=True
    )
    mode = models.IntegerField(
        verbose_name='控制模式',
        default=0,
        null=True
    )
    default_value = models.IntegerField(
        verbose_name='初始默认值',
        null=True
    )
    u_id = models.IntegerField(
        verbose_name='下标',
        default=0,
        null=True
    )

    class Meta:
        db_table = 'controls'
        unique_together = ('id', 'u_id',)
        permissions = (
            ('controls_post', '添加控制器'),
            ('controls_patch', '修改控制器'),
            ('controls_delete', '删除控制器'),
            ('controls_get', '查询查询控制器'),
            ('controls_status', '打开关闭继电器'),
        )
        default_permissions = ()


class Sensor(models.Model):
    id = models.BigAutoField(
        primary_key=True
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    unit = models.CharField(
        max_length=255,
        default="",
        null=False,
        verbose_name='名称'
    )
    measuring = models.IntegerField(
        verbose_name='输入1~N测量种类'
    )
    start = models.IntegerField(
        verbose_name='开始'
    )
    input_number = models.IntegerField(
        verbose_name='编号'
    )
    name = models.CharField(
        max_length=255,
        verbose_name='名称'
    )
    status = models.IntegerField(
        verbose_name='是否使用'
    )
    led_status = models.IntegerField(
        verbose_name='LED状态'
    )
    addr_485 = models.BigIntegerField(
        verbose_name='485地址'
    )
    end_type = models.IntegerField(
        verbose_name='大小端'
    )
    data_format = models.BigIntegerField(
        verbose_name='数据类型'
    )
    register_start = models.BigIntegerField(
        verbose_name='开始'
    )
    register_length = models.IntegerField(
        verbose_name='长度'
    )
    ratio_a = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数a'
    )
    ratio_b = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b'
    )
    devices = models.ForeignKey(
        Devices,
        models.CASCADE
    )
    warn_max_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    warn_min_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    u_id = models.IntegerField(
        verbose_name='区别设备'
    )

    class Meta:
        db_table = 'sensor'
        unique_together = (('devices', 'u_id'),)
        permissions = (
            ('sensor485_post', '添加485传感器'),
            ('sensor485_patch', '修改485传感器'),
            ('sensor485_delete', '删除485传感器'),
            ('sensor485_get', '查询485传感器'),
        )
        default_permissions = ()

    def append(self, data):
        SensorCache(
            f'{self.devices_id}_{self.id}_{self.input_number}').append(data)

    def get_all(self):
        return SensorCache(
            f'{self.devices_id}_{self.id}_{self.input_number}').get_all()


class AutoRule(models.Model):
    id = models.AutoField(
        primary_key=True,
        unique=True
    )
    name = models.CharField(
        max_length=255,
        verbose_name="自动规则别名",
        default="暂无名称"
    )
    rule_code = models.IntegerField(
        verbose_name='开始标志'
    )
    rule_number = models.IntegerField(
        verbose_name='编号'
    )
    status = models.IntegerField(
        verbose_name='规则1~N是否启用'
    )
    time_status = models.IntegerField(
        verbose_name='时间段是否开启'
    )
    time_start = models.CharField(
        max_length=255,
        verbose_name='规则1~N时间段开始点'
    )
    time_end = models.CharField(
        max_length=255,
        verbose_name='规则1~N时间段结束点'
    )
    rule_status_1 = models.IntegerField(
        verbose_name='条件1_启用'
    )
    rule_close_value_1 = models.IntegerField(
        verbose_name='条件1_不启用时逻辑值'
    )
    rule_input_type_1 = models.IntegerField(
        verbose_name='条件1_输入种类'
    )
    rule_input_channel_1 = models.IntegerField(
        verbose_name='条件1_输入路号'
    )
    rule_input_collection_1 = models.IntegerField(
        verbose_name='条件1_输入采集量'
    )
    rule_compare_1 = models.IntegerField(
        verbose_name='条件1_比较'
    )
    rule_threshold_1 = models.IntegerField(
        verbose_name='条件1_门限值'
    )
    rule_float_1 = models.IntegerField(
        verbose_name='条件1_浮动值'
    )
    rule_operation = models.IntegerField(
        verbose_name='条件运算'
    )
    rule_status_2 = models.IntegerField(
        verbose_name='条件2_启用'
    )
    rule_close_value_2 = models.IntegerField(
        verbose_name='条件2_不启用时逻辑值'
    )
    rule_input_type_2 = models.IntegerField(
        verbose_name='条件2_输入种类'
    )
    rule_input_channel_2 = models.IntegerField(
        verbose_name='条件2_输入路号'
    )
    rule_compare_2 = models.IntegerField(
        verbose_name='条件2_比较'
    )
    rule_threshold_2 = models.IntegerField(
        verbose_name='条件2_门限值'
    )
    rule_float_2 = models.IntegerField(
        verbose_name='条件2_浮动值'
    )
    output_type = models.IntegerField(
        verbose_name='规则1~N输出类型'
    )
    output_channle = models.IntegerField(
        verbose_name='规则1~N输出路号'
    )
    rule_input_collection_2 = models.IntegerField(
        verbose_name='条件2_输入采集量'
    )
    output_value = models.CharField(
        max_length=255,
        verbose_name='规则1~N输出值'
    )
    devices = models.ForeignKey(
        'Devices',
        models.CASCADE,
        null=True
    )
    u_id = models.IntegerField(
        verbose_name='唯一ID'
    )

    class Meta:
        db_table = 'auto_rule'
        unique_together = (('u_id', 'devices'),)
        permissions = (
            ('autorule_post', '添加自动规则'),
            ('autorule_patch', '修改自动规则'),
            ('autorule_delete', '删除自动规则'),
            ('autorule_get', '查询自动规则'),
        )
        default_permissions = ()


class MockSensor(models.Model):
    devices = models.ForeignKey(
        'Devices',
        models.CASCADE
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    u_id = models.IntegerField(
        verbose_name='uniid'
    )
    name = models.CharField(
        max_length=255,
        verbose_name='名称'
    )
    start = models.IntegerField(
        verbose_name='有效标志'
    )
    number = models.IntegerField(
        verbose_name='编号'
    )
    is_use = models.IntegerField(
        verbose_name='是否开启'
    )
    led_is_use = models.IntegerField(
        verbose_name='LED是否开启'
    )
    measuring = models.IntegerField(
        verbose_name='输入1~N测量种类'
    )
    value_type = models.IntegerField(
        verbose_name='模拟量类型  0：模拟量4~20mA   1：0~5V    2，0~10V'
    )
    input_serial_number_a = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='输入1~N系数A，'
    )
    input_serial_number_b = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='输入1~N系数b'
    )
    warn_max_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    warn_min_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    unit = models.CharField(
        max_length=255,
        default="",
        null=False,
        verbose_name='单位'
    )

    class Meta:
        db_table = 'mock_sensor'
        unique_together = (('devices', 'u_id'),)
        permissions = (
            ('mock_sensor_post', '添加模拟量传感器'),
            ('mock_sensor_patch', '修改模拟量传感器'),
            ('mock_sensor_delete', '删除模拟量传感器'),
            ('mock_sensor_get', '查询模拟量传感器'),

        )
        default_permissions = ()


class History(models.Model):
    devices = models.ForeignKey(
        'Devices',
        models.CASCADE
    )
    sensor = models.ForeignKey(
        'Sensor', models.CASCADE,
        null=True
    )
    mock_sensor = models.ForeignKey(
        'MockSensor',
        models.CASCADE,
        null=True
    )
    number_sensor = models.ForeignKey(
        'NumberSensor',
        models.CASCADE,
        null=True
    )
    time_ticket = models.BigIntegerField(
        null=False,
        verbose_name='数据时间戳'
    )
    data_format = models.IntegerField(
        null=False,
        verbose_name='输入种类'
    )
    input_channel = models.IntegerField(
        null=False,
        verbose_name='输入种类'
    )
    input_type = models.IntegerField(
        null=False,
        verbose_name='输入种类'
    )
    data = models.CharField(
        max_length=255,
        null=False,
        verbose_name='数据'
    )
    collection = models.IntegerField(
        null=False,
        verbose_name='输入1~N测量种类',
        default=0
    )



    class Meta:
        db_table = 'sensor_history'
        permissions = (
            ('log_get', '读取日志'),
        )
        default_permissions = ()


class ControlGroup(models.Model):
    id = models.BigAutoField(
        primary_key=True
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    alias = models.CharField(
        max_length=255,
        verbose_name='组合控制别名'
    )
    start = models.IntegerField(
        verbose_name='有效标识'
    )
    number = models.IntegerField(
        max_length=255,
        verbose_name='编号',
        null=False
    )
    is_use = models.IntegerField(
        verbose_name='是否启用'
    )
    mode = models.IntegerField(
        verbose_name='控制模式'
    )
    group_mode = models.IntegerField(
        verbose_name='组合模式'
    )
    sub_device_1 = models.IntegerField(
        verbose_name='子设备1'
    )
    sub_device_2 = models.IntegerField(
        verbose_name='子设备2'
    )
    default_value = models.IntegerField(
        verbose_name='初始默认值'
    )
    u_id = models.IntegerField(
        max_length=255,
        verbose_name='编号',
        null=False
    )
    devices = models.ForeignKey(
        Devices,
        on_delete=models.SET_NULL,
        null=True,
        verbose_name='设备'
    )

    class Meta:
        db_table = 'control_group'
        unique_together = (('devices', 'u_id'),)
        permissions = (
            ('control_group_post', '添加控制组'),
            ('control_group_patch', '修改控制组'),
            ('control_group_delete', '删除控制组'),
            ('control_group_get', '查询控制组'),
            ('control_group_status', '打开控制组'),
        )
        default_permissions = ()


class MockControls(models.Model):
    id = models.BigAutoField(
        primary_key=True
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    name = models.CharField(
        max_length=255,
        verbose_name='组合控制别名'
    )
    start = models.IntegerField(
        verbose_name='有效标识'
    )
    number = models.CharField(
        max_length=255,
        verbose_name='编号',
        null=False
    )
    is_use = models.IntegerField(
        verbose_name='是否启用'
    )
    mode = models.IntegerField(
        verbose_name='控制模式'
    )
    default_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='初始默认值'
    )

    u_id = models.IntegerField(
        max_length=255,
        verbose_name='编号',
        null=False
    )
    devices = models.ForeignKey(
        Devices,
        on_delete=models.SET_NULL,
        null=True,
        verbose_name='设备'
    )

    class Meta:
        db_table = 'mock_control'
        unique_together = (('devices', 'u_id'),)
        permissions = (
            ('mock_controls_post', '添加模拟量继电器'),
            ('mock_controls_patch', '修改模拟量继电器'),
            ('mock_controls_delete', '删除模拟量继电器'),
            ('mock_controls_get', '查询模拟量继电器'),
        )
        default_permissions = ()


class DeviceVideoMonitor(models.Model):
    """
        设备视频监控
    """
    id = models.BigAutoField(
        primary_key=True,
        unique=True,
        verbose_name="主键"
    )
    video_url = models.CharField(
        max_length=255,
        null=False,
        default="",
        verbose_name="视频监控URL"
    )
    desc = models.CharField(
        max_length=255,
        null=False,
        default='',
        verbose_name="备注"
    )
    devices = models.ForeignKey(
        Devices,
        null=True,
        on_delete=models.SET_NULL,
        verbose_name="设备"
    )

    class Meta:
        db_table = "device_video_monitor"
        permissions = (
            ('video_post', '添加视频监控'),
            ('video_patch', '修改视频监控'),
            ('video_delete', '删除视频监控'),
            ('video_get', '查询视频监控'),
        )
        default_permissions = ()


class NumberSensor(models.Model):
    id = models.BigAutoField(
        primary_key=True
    )
    icon = models.CharField(
        max_length=255,
        null=True,
        default=''
    )
    unit = models.CharField(
        max_length=255,
        default="",
        null=False,
        verbose_name='名称'
    )
    start = models.IntegerField(
        verbose_name="编号"
    )
    number = models.IntegerField(
        verbose_name="编号"
    )
    measuring = models.IntegerField(
        verbose_name='输入1~N测量种类'
    )
    name = models.CharField(
        max_length=255,
        verbose_name="名称"
    )
    is_use = models.IntegerField(
        verbose_name="是否使用"
    )
    led_is_use = models.IntegerField(
        verbose_name="LED是否使用"
    )
    get_value_setting = models.IntegerField(
        verbose_name="0：取值与输入电平相同  1：取值与输入电平相反"
    )
    warn_max_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    warn_min_value = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        verbose_name='系数b',
        default=0
    )
    u_id = models.IntegerField(verbose_name="服务器标志")
    devices = models.ForeignKey(
        'Devices',
        on_delete=models.CASCADE,
        verbose_name="关联的设备"
    )

    class Meta:
        db_table = "number_sensor"
        unique_together = (('devices', 'u_id'),)
        permissions = (
            ('number_sensor_post', '添加视频监控'),
            ('number_sensor_patch', '修改视频监控'),
            ('number_sensor_delete', '删除视频监控'),
            ('number_sensor_get', '查询视频监控'),
        )
        default_permissions = ()
